package com.yc.service;

import com.yc.bean.Account;
import com.yc.bean.OpType;
import com.yc.bean.Oprecord;
import com.yc.dao.AccountDao;
import com.yc.dao.OpRecordDao;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author zwei
 * @create 2024-08-08 14:17
 */
@Service
@Log4j
@Transactional(
        propagation = Propagation.REQUIRED,
        isolation = org.springframework.transaction.annotation.Isolation.READ_COMMITTED,
        timeout=-1,
        readOnly = false,
        rollbackFor = RuntimeException.class
)
public class BankBizImpl implements BankBiz {
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private OpRecordDao opRecordDao;

    @Override
    public Account openAccount(double money) {
        //开户
        int accountid = accountDao.insert(money);
        //流水记录
        Oprecord oprecord = new Oprecord();
        oprecord.setAccountid(accountid);
        oprecord.setOpmoney(money);
        oprecord.setOptype(OpType.DEPOSITE);
        opRecordDao.insertOpRecord(oprecord);
        //构建返回值
        Account a = new Account();
        a.setAccountid(accountid);
        a.setBalance(money);
        log.debug("新开户：" + accountid + ",存入：" + money);
        return a;
    }
    @CachePut(cacheNames = "bank_web", key = "#accountid")
    @Override
    public Account deposite(int accountid, double money) {
        Account a = null;
        try {
            a = this.findAccount(accountid);
        } catch (Exception e) {
            log.error("账户不存在：" + accountid);
            throw new RuntimeException("查无此账户" + accountid + ",无法完成存款操作");
        }
        a.setBalance(a.getBalance() + money);
        this.accountDao.update(accountid, a.getBalance());
        //流水记录
        Oprecord oprecord = new Oprecord();
        oprecord.setAccountid(accountid);
        oprecord.setOpmoney(money);
        oprecord.setOptype(OpType.DEPOSITE);
        opRecordDao.insertOpRecord(oprecord);
        return a;
    }
    @CachePut(cacheNames = "bank_web", key = "#accountid")
    @Override
    public Account withdraw(int accountid, double money) {
        Account a = null;
        try {
            a = this.findAccount(accountid);
        } catch (Exception e) {
            log.error("账户不存在：" + accountid);
            throw new RuntimeException("查无此账户" + accountid + ",无法完成取款操作");
        }
        //流水记录
        Oprecord oprecord = new Oprecord();
        oprecord.setAccountid(accountid);
        oprecord.setOpmoney(money);
        oprecord.setOptype(OpType.WITHDRAW);
        opRecordDao.insertOpRecord(oprecord);
        //TODO: 这里要判断余额是否足够   因数据库中余束会检查余额是否足够
        a.setBalance(a.getBalance() - money);
        this.accountDao.update(accountid, a.getBalance());
        return a;
    }
    @CachePut(cacheNames = "bank_web", key = "#accountid")
    @Override
    public Account transfer(int accountid, double money, int toAccountid) {
        this.deposite(toAccountid, money);
        Account a = this.withdraw(accountid, money);
        return a;
    }

    @Cacheable(cacheNames = "bank_web", key = "#accountid")
    @Override
    public Account findAccount(int accountid) {
        return this.accountDao.findById(accountid);
    }
}
